/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package fr.ove.clientserver;

/**
 *
 * @author Mr.Sam
 */
import java.io.*;
import java.net.*;
import java.util.*;
import fr.ove.clientserver.events.*;

/**
* A socket server.
*/
public class SocketServer implements Runnable {    
    /**
    * The port number used on the host to run the socket server.
    */
    private int portNumber;
    
    /**
    * The socket server.
    */
    private ServerSocket serverSocket;
    
    /**
    * The listener of the instance. Should be the server by itself
    */
    private SocketServerListener listener = null;
    
    /**
    * The default constructor.<BR>
    * The default is a socket server running on port 6666 and allowing the creation
    * of a maximum of 300 sockets.
    */
    public SocketServer() throws IOException {
        this(6666, 300);
    }
    
    
    /**
    * The constructor.
    * @param portNumber the port number used on the host to run the socket server.
    * @param maxSocket the maximu number of socket created allowed.
    */
    public SocketServer(int portNumber, int maxSocket) throws IOException {
        this.portNumber = portNumber;
        // Create the socket server.
        // If creation failed, IOException is thrown
        serverSocket = new ServerSocket(portNumber, maxSocket);
        // Create a Thread running the instance and start it.
        new Thread(this).start();
    }
    
    /**
    * Registers a listener to the instance.
    * @param listener the listener to register.
    */
    public synchronized void addSocketServerListener(SocketServerListener listener) throws TooManyListenersException {
        if (listener != null)
            this.listener = listener;
        else
            throw new TooManyListenersException();
    }
    
    /**
    * Removes a registered listener from the instance.
    * @param listener the listener to remove.
    */
    public synchronized void removeSocketServerListener(SocketServerListener listener) {
        if (this.listener == listener)
            this.listener = null;
    }
    
    /**
    * Fires an event to the registered listeners of the instance.
    * @param evt the event to fire.
    */
    public synchronized void fireSocketServerEvent(SocketServerEvent evt) {
        listener.socketAccepted(evt);
    }
    
    // Runnable interface implementation.
    
    /**
    * Run the socket server.
    */
    public void run() {
        try {
            Socket socket = null;
            SocketServerEvent evt = new SocketServerEvent(this);
            
            while (true) {
                socket = serverSocket.accept();
                evt.setSocket(socket);
                fireSocketServerEvent(evt);
            }
        }
        catch (IOException ioe) {
            System.out.println("Something occurred while waiting for socket");
            ioe.printStackTrace();
        }
    }
}